import React, { Component } from 'react';
import { DownOutlined, UpOutlined } from '@ant-design/icons';
import '@ant-design/compatible/assets/index.css';
import { Row, Col, Input, Button, Select, DatePicker, InputNumber, Cascader, Form } from 'antd';
import { FormInstance } from 'antd/lib/form';
import { connect } from 'dva';
import styles from './style.less';
import { transferOption } from '@/support/utils';

/**
 *  可使用的类型
 *  input(输入)
 *  select(选择)
 *  datePicker(日期选择)
 *  inputNumber（数字输入）
 *  rangePicker（时间段选择）需要配合blank一起使用
 *  cascader（级联选择）
 */

const FormItem = Form.Item;
const { RangePicker } = DatePicker;

@connect()
export default class PateoSearchForm extends Component<any, any> {
  formRef = React.createRef<FormInstance>();
  state = {
    isExtend: this.props.isExtend,
    sourceExtend: this.props.isExtend,
  };

  componentDidMount() {
    const { searchItems, onRef } = this.props;
    if (onRef) {
      onRef(this.formRef);
    }
    const fields = [];
    for (let index in searchItems) {
      const item = searchItems[index];
      if (item.initialValue) {
        fields.push({ name: item.key, value: item.initialValue });
      }
    }
    this.formRef.current.setFields(fields);
  }

  // 父组件传入 isExtend 变更
  componentDidUpdate(prevProps: any) {
    const { sourceExtend } = this.state;
    if (sourceExtend !== prevProps.isExtend) {
      this.setState({
        isExtend: prevProps.isExtend,
        sourceExtend: prevProps.isExtend,
      });
    }
  }

  onFinish = fieldsValue => {
    const {
      fetchParams: { type, url },
      saveFormValues,
      handleFieldsValue,
      dispatch,
      extraArgs = {},
      dispatchFn,
    } = this.props;
    let values = null;
    if (handleFieldsValue) {
      values = handleFieldsValue(fieldsValue);
      if (values === false) {
        return;
      }
    } else {
      values = { ...fieldsValue };
    }
    // 当前的搜索条件进行保存
    if (saveFormValues) {
      saveFormValues(values);
    }

    if (dispatchFn) {
      dispatchFn && dispatchFn({ ...values, ...extraArgs });
    } else {
      dispatch({
        type,
        payload: { url, ...values, ...extraArgs },
      });
    }
  };

  handleFormReset = () => {
    const { searchItems = {}, handleFormReset, initFields = undefined } = this.props;
    const fields = [];
    for (let index in searchItems) {
      const item = searchItems[index];
      if (!item.rules) {
        fields.push({ name: item.key, value: undefined });
      }
    }
    // this.formRef.current.setFields(fields);
    this.formRef.current.resetFields();
    if (initFields) {
      this.formRef.current?.setFieldsValue(initFields)
    }
    if (handleFormReset) {
      let result = handleFormReset();
      if (result === false) {
        return;
      }
    }
    this.formRef.current.submit();
  };

  renderForm = () => {
    const { searchItems = [] } = this.props;
    const { isExtend } = this.state;
    const loopFormItems = data =>
      data.map((item, index) => {
        if (!isExtend && index > 1) {
          return null;
        }
        const { type, rules = [], initialValue, formItemProps = {} } = item; // 每种类型必传3属性   title  key  type
        const options = {
          rules,
          initialValue,
        };
        switch (type) {
          case 'input': {
            const {
              title,
              key,
              type,
              rules,
              initialValue,
              customStyle = 8,
              formItemProps = {},
              ...rest
            } = item;
            const placeholder = `请输入${typeof title === 'string' ? title : ''}`;
            return (
              <Col span={customStyle} key={key}>
                <FormItem {...formItemProps} name={key} label={title} initialValue={initialValue} rules={rules}>
                  <Input placeholder={placeholder} autoComplete="off" allowClear {...rest} />
                </FormItem>
              </Col>
            );
          }
          case 'select': {
            const {
              title,
              key,
              type,
              selectOptions = [],
              optionsType = 'kv', // kv为key，value的意思，如果为'kv'，那么selectOptions为js对象，如果为'option'，那么selectOptions为jsx的option对象。
              keyValue = ['value', 'label'],
              onSelectChange,
              filterOption,
              showSearch = true,
              rules,
              initialValue,
              customStyle = 8,
              ...rest
            } = item;
            const extra = showSearch
              ? filterOption
                ? {
                    showSearch: true,
                    optionFilterProp: 'children',
                    filterOption,
                  }
                : {
                    showSearch: true,
                    optionFilterProp: 'children',
                  }
              : {};
            return (
              <Col span={customStyle} key={key}>
                <FormItem {...formItemProps} name={key} label={title} initialValue={initialValue} rules={rules}>
                  <Select
                    style={{width: 200}}
                    placeholder="请选择"
                    allowClear
                    onChange={onSelectChange}
                    getPopupContainer={triggerNode => triggerNode.parentNode}
                    {...extra}
                    {...rest}
                  >
                    {optionsType === 'kv' ? transferOption(selectOptions, keyValue) : selectOptions}
                  </Select>
                </FormItem>
              </Col>
            );
          }
          case 'datePicker': {
            const {
              title,
              key,
              type,
              format = 'YYYY-MM-DD',
              showTime = false,
              style,
              rules,
              initialValue,
              ...rest
            } = item;
            return (
              <Col span={8} key={key}>
                <FormItem {...formItemProps} name={key} initialValue={initialValue} label={title} rules={rules}>
                  <DatePicker
                    allowClear
                    placeholder="请选择"
                    showTime={showTime}
                    showToday
                    format={format}
                    style={{ width: '100%', ...style }}
                    getCalendarContainer={trigger => trigger.parentNode}
                    {...rest}
                  />
                </FormItem>
              </Col>
            );
          }
          case 'inputNumber': {
            const { title, key, type, style, rules, initialValue, ...rest } = item;
            return (
              <Col span={8} key={key}>
                <FormItem {...formItemProps} name={key} label={title} initialValue={initialValue} rules={rules}>
                  <InputNumber
                    allowClear
                    autoComplete="off"
                    placeholder="请输入"
                    style={{ width: '100%', ...style }}
                    {...rest}
                  />
                </FormItem>
              </Col>
            );
          }
          case 'rangePicker': {
            const {
              title,
              key,
              type,
              format = 'YYYY-MM-DD HH:mm:ss',
              showTime = true,
              style,
              customStyle = 10,
              rules,
              initialValue,
              ...rest
            } = item;
            return (
              <Col span={customStyle} key={key}>
                <FormItem {...formItemProps} name={key} label={title} rules={rules}>
                  <RangePicker
                    allowClear
                    placeholder={['开始时间', '结束时间']}
                    showTime={showTime}
                    style={{ width: '100%', ...style }}
                    format={format}
                    defaultValue={initialValue}
                    getCalendarContainer={trigger => trigger.parentNode}
                    {...rest}
                  />
                </FormItem>
              </Col>
            );
          }
          // rangePicker时间段选择调整样式.  时间段样式为   1个或2个必须单独占一行
          // 例如一个时间段选择  12  6  6  两个时间段选择 12  12  0
          // 必须保证  customStyle总和为24且必须有3个
          case 'blank': {
            const { key, customStyle = 4 } = item;
            return (
              <Col span={customStyle} key={key}>
                <FormItem {...formItemProps} key={key}></FormItem>
              </Col>
            );
          }
          case 'cascader': {
            const {
              title,
              key,
              type,
              selectOptions = [],
              style,
              showSearch = false,
              separator = '--',
              rules,
              initialValue,
              ...rest
            } = item;
            const extra = showSearch
              ? {
                  showSearch: (inputValue, path) =>
                    path.some(
                      option => option.label.toLowerCase().indexOf(inputValue.toLowerCase()) > -1,
                    ),
                }
              : {};
            return (
              <Col span={8} key={key}>
                <FormItem {...formItemProps} name={key} label={title} initialValue={initialValue} rules={rules}>
                  <Cascader
                    allowClear
                    placeholder="请选择"
                    displayRender={label => label.join(separator)}
                    options={selectOptions}
                    style={{ width: '100%', ...style }}
                    getPopupContainer={triggerNode => triggerNode.parentNode}
                    {...extra}
                    {...rest}
                  />
                </FormItem>
              </Col>
            );
          }
        }
      });
    return loopFormItems(searchItems);
  };
  render() {
    const { searchItems = [], btnSize, customStyle, extendOffset = undefined } = this.props;
    const { isExtend } = this.state;
    const offset =
      searchItems.length <= 2
        ? 16 - (searchItems.length % 3) * 8
        : isExtend
        ? (extendOffset ?? 16 - (searchItems.length % 3) * 8)
        : 0;
    return (
      <div className={styles.tableListForm}>
        <Form ref={this.formRef} onFinish={this.onFinish}>
          <Row gutter={24} className={styles.my_searchRow}>
            {this.renderForm()}
            <Col span={customStyle ? customStyle : 8} offset={offset} style={{marginTop: '10px'}}>
              <span style={{ float: 'right' }}>
                <Button type="primary" size={btnSize || 'small'} htmlType="submit">
                  查询
                </Button>
                <Button
                  size={btnSize || 'small'}
                  style={{ marginLeft: 8 }}
                  onClick={this.handleFormReset}
                >
                  重置
                </Button>
                {searchItems.length > 2 ? (
                  <a
                    style={{ marginLeft: 8 }}
                    onClick={() => this.setState({ isExtend: !isExtend })}
                  >
                    {!isExtend ? (
                      <span>
                        展开 <DownOutlined />
                      </span>
                    ) : (
                      <span>
                        收起 <UpOutlined />
                      </span>
                    )}
                  </a>
                ) : null}
              </span>
            </Col>
          </Row>
        </Form>
      </div>
    );
  }
}
